package me.jtx.poplar.user.web.controller;

import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import me.jtx.poplar.core.exception.auth.AuthCredentialsMissingException;
import me.jtx.poplar.core.exception.auth.AuthenticationFailedException;
import me.jtx.poplar.core.validation.Validity;
import me.jtx.poplar.user.Key;
import me.jtx.poplar.user.Route;
import me.jtx.poplar.user.model.entity.User;
import me.jtx.poplar.user.model.entity.request.UserRO;
import me.jtx.poplar.user.service.UserService;
import me.jtx.poplar.user.web.View;

/**
 * The Merchant entity registration and related pages handler
 *
 * @author: Tong Huazhong(jsyzthz@gmail.com)
 * @copyright: &copy; 2016, Tong Huazhong
 */
@Controller
public class UserController extends BaseWebAppController {
	private Logger log = LoggerFactory.getLogger(UserController.class);
	private @Autowired UserService userService;

	/**
	 * Show registration page
	 *
	 * @param locale
	 * @param model
	 *
	 * @return
	 */
	@RequestMapping(value = Route.USER_REGISTRATION, method = RequestMethod.GET)
	public String userRegistration(Locale locale, Model model) {
		return View.userRegistration;
	}

	/**
	 * Login a merchant
	 *
	 * @param locale
	 * @param model
	 * @param userRO
	 *
	 * @return
	 */
	@RequestMapping(value = Route.loginUser, method = RequestMethod.POST)
	public String loginMerchant(Locale locale, Model model, @ModelAttribute(Key.loginUserForm) UserRO userRO) {
		try {
			// Authenticate the credentials
			if ((userRO.username != null && userRO.username.trim().length() > 0)
					&& (userRO.password != null && userRO.password.trim().length() > 0)) {
				final User user = userService.findByUsername(userRO.username);
				log.info("User Found: " + user.getUserName());

				if (user.getPassWord().equals(User.hashPassword(userRO.password))) {
					log.info("Authenticated: " + user.getUserName());

					// Update the login count and other info
					userService.loginUser(user, request);

					// Store the user in session
					request.getSession(true).setAttribute(Key.userInSession, user);
					model.addAttribute("ls", true);
					return Key.redirect + Route.dashboard;
				} else {
					log.info("User Authentication Failed: " + user.getUserName());
					throw new AuthenticationFailedException("");
				}
			} else {
				throw new AuthCredentialsMissingException("");
			}
		} catch (Exception e) {
			log.error(e.getMessage());
			addError("login error", model);
			addError(e.getMessage(), model);
			return View.HOME;
		}
	}

	/**
	 * Registers new users
	 *
	 * @param locale
	 * @param model
	 * @param userRO
	 *
	 * @return
	 */
	@RequestMapping(value = Route.registerUser, method = RequestMethod.POST, consumes = Key.formEncoded)
	public String registerUser(Locale locale, Model model, @ModelAttribute(Key.regUserForm) UserRO userRO) {
		try {
			User u = userRO.user(props);
			Validity validity = userService.validate(u);
			if (validity.isValid()) {
				userService.registerUser(u, request);
				// mailSenderActor.sendUserEmailIdConfirmationMail(u);
				request.getSession(true).setAttribute(Key.userInSession, u);
				model.addAttribute(Key.isRegister, true);
				return Key.redirect + Route.dashboard;
			} else {
				addError("reg error", model);
				return View.userRegistration;
			}
		} catch (Exception e) {
			log.error(e.getMessage());
			addError("reg error", model);
			addError(e.getMessage(), model);
			return View.userRegistration;
		}
	}

	/**
	 * Logs out a merchant by deleting the session
	 *
	 * @param locale
	 * @param model
	 *
	 * @return
	 */
	@RequestMapping(value = Route.logoutUser, method = RequestMethod.GET)
	public String logoutUser(Locale locale, Model model) {
		request.getSession().removeAttribute(Key.userInSession);
		return "redirect:" + Route.HOME;
	}
}
